package com.study.lxy.springcloud.common.handler;

import com.study.lxy.springcloud.common.constance.CommonRespEnum;
import com.study.lxy.springcloud.common.exception.BusiException;
import com.study.lxy.springcloud.common.format.ServiceResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;

@RestControllerAdvice
public class GlobleExceptionHandler extends ResponseEntityExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobleExceptionHandler.class);
    /**
     * 定义要捕获的异常 可以多个 @ExceptionHandler({})
     *
     * @param e exception
     * @param response response
     * @return 响应结果
     */
    @ExceptionHandler(BusiException.class)
    public ServiceResp busiExceptionHandler(final Exception e, HttpServletResponse response){
        response.setStatus(HttpStatus.OK.value());
        BusiException exception = (BusiException) e;
        logger.warn("request failed,responseCode={},message={}",exception.getCode(),exception.getMessage(),e);
        return ServiceResp.fail(exception.getCode(),exception.getMessage());
    }
    /**
     * 定义要捕获的异常 可以多个 @ExceptionHandler({})
     * @param e        exception
     * @param response response
     * @return 响应结果
     */
    @ExceptionHandler(SQLException.class)
    public ServiceResp sqlExceptionHandler(final Exception e, HttpServletResponse response){
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        logger.error("sql exception!!!",e);
        return ServiceResp.fail("0999","系统异常，请稍后重试");
    }
    /**
     * 通用的接口映射异常处理方
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        logger.error("unhandlered exception.",ex);
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(ServiceResp.fail(String.valueOf(status.value()), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
            logger.error("参数转换失败，方法：" + exception.getParameter().getMethod().getName() + "，参数：" + exception.getName()
                    + ",信息：" + exception.getLocalizedMessage());
            return new ResponseEntity<>(ServiceResp.fail(String.valueOf(status.value()), "参数转换失败"), status);
        }
        return new ResponseEntity<>(ServiceResp.fail(CommonRespEnum.COMMON_ERROR.getCode(), CommonRespEnum.COMMON_ERROR.getMessage()), status);
    }
}
